#ifndef SIMP_LOG_M_H
#define SIMP_LOG_M_H

#include "stdint.h"
#include "rtctime.h"

#ifdef __cplusplus
extern "C"
{
#endif

	typedef struct
	{
		uint32_t blocks;
		uint32_t blocks_per_page;
		uint32_t site_start;
		uint32_t site_next;
	} simp_log_info_type;

	typedef struct
	{
		void (*save)(void *dat);
		void (*save_verify)(void *dat);
		void (*init)(void);
		void (*read)(uint32_t site, void *pdat);
		void (*clr)(void);
		char (*is_site_valid)(int32_t site);
		int32_t (*site_move)(int32_t site, int32_t offset);
		int32_t (*time_search)(uint32_t time, int8_t mode);
		int32_t (*type_search)(uint8_t flag_msk, uint8_t log_flag, int32_t num, int32_t *site_des);
	} simp_log_api_type;

	typedef struct
	{
		uint32_t addr_base;	 
		uint32_t total_size; 
		uint16_t page_size;	 
		uint16_t dat_size;	 
		simp_log_info_type *info;
		void (*Erase)(uint32_t AddrBase);			  
		void (*Program)(uint32_t Addr, uint32_t dat); 
		uint32_t (*Read)(uint32_t Addr);			  
		const simp_log_api_type *api;
	} simp_log_type;

	void simp_log_save(const simp_log_type *cfg, void *dat);
	void simp_log_save_verify(const simp_log_type *cfg, void *dat);
	void simp_log_init(const simp_log_type *cfg);
	void simp_log_read(const simp_log_type *cfg, uint32_t site, void *pdat);
	void simp_log_clr(const simp_log_type *cfg);
	int32_t simp_log_site_move(const simp_log_type *cfg, int32_t site, int32_t offset);
	char simp_log_is_site_valid(const simp_log_type *cfg, int32_t site);
	int32_t simp_log_flag_search(const simp_log_type *cfg, uint8_t flag_msk, uint8_t log_flag, int32_t num, int32_t *site_des); 

	int32_t simp_log_time_search(const simp_log_type *cfg, uint32_t time, int8_t mode); 

#define simp_log_api_make(obj)                                                                     \
                                                                                                   \
	void obj##_save(void *dat);                                                                    \
	void obj##_save_verify(void *dat);                                                             \
	void obj##_init(void);                                                                         \
	void obj##_read(uint32_t site, void *pdat);                                                    \
	void obj##_clr(void);                                                                          \
	char obj##_is_site_valid(int32_t site);                                                        \
	int32_t obj##_site_move(int32_t site, int32_t offset);                                         \
	int32_t obj##_time_search(uint32_t time, int8_t mode);                                    \
	int32_t obj##_flag_search(uint8_t flag_msk, uint8_t log_flag, int32_t num, int32_t *site_des); \
                                                                                                   \
	void obj##_save(void *dat)                                                                     \
	{                                                                                              \
		simp_log_save(&obj, dat);                                                                  \
	}                                                                                              \
	void obj##_save_verify(void *dat)                                                              \
	{                                                                                              \
		simp_log_save_verify(&obj, dat);                                                           \
	}                                                                                              \
	void obj##_init(void)                                                                          \
	{                                                                                              \
		simp_log_init(&obj);                                                                       \
	}                                                                                              \
	void obj##_read(uint32_t site, void *pdat)                                                     \
	{                                                                                              \
		simp_log_read(&obj, site, pdat);                                                           \
	}                                                                                              \
	void obj##_clr(void)                                                                           \
	{                                                                                              \
		simp_log_clr(&obj);                                                                        \
	}                                                                                              \
	char obj##_is_site_valid(int32_t site)                                                         \
	{                                                                                              \
		return simp_log_is_site_valid(&obj, site);                                                 \
	}                                                                                              \
	int32_t obj##_site_move(int32_t site, int32_t offset)                                          \
	{                                                                                              \
		return simp_log_site_move(&obj, site, offset);                                             \
	}                                                                                              \
	int32_t obj##_time_search(uint32_t time, int8_t mode)                                     \
	{                                                                                              \
		return simp_log_time_search(&obj, time, mode);                                             \
	}                                                                                              \
	int32_t obj##_flag_search(uint8_t flag_msk, uint8_t log_flag, int32_t num, int32_t *site_des)  \
	{                                                                                              \
		return simp_log_flag_search(&obj, flag_msk, log_flag, num, site_des);                      \
	}                                                                                              \
	const simp_log_api_type obj##_api = {                                                          \
		obj##_save,                                                                                \
		obj##_save_verify,                                                                         \
		obj##_init,                                                                                \
		obj##_read,                                                                                \
		obj##_clr,                                                                                 \
		obj##_is_site_valid,                                                                       \
		obj##_site_move,                                                                           \
		obj##_time_search,                                                                         \
		obj##_flag_search}
#define simp_log_api_ref(obj) extern const simp_log_api_type obj##_api
#define simp_log_api_name(obj) &obj##_api

#ifdef __cplusplus
}
#endif

#endif 
